using Musi;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class GameButtonPanel : ButtonPanel
{
    public ChartTime currentTime;
    public Chart chart;

    private List<GameButton> buttons;

    public Text SongName;
    public Text ChartDescription;
    public Text TimeText;
    public Text ComboText;
    public Text ScoreTypeText;

    public Animator ScoreTypeAnimator;

    public GameObject EndPanel;
    public GameObject InfoPanel;

    private bool isEnd = false;
    private GameScore score;

    protected override void InitializeEvent()
    {
        /*
         * Initialize score
         */
        if (score == null)
        {
            score = new GameScore();
        }

        /*
         * Initialize button event
         */
        List<ButtonPos> buttonsPos = buttonManager.AllButtons;
        buttons = new List<GameButton>(); // get all buttons

        foreach (ButtonPos buttonPos in buttonsPos) // add click event for each button
        {
            buttons.Add(buttonPos.gameObject.GetComponent<GameButton>());
            buttonManager.ChangeOnClickEvent(buttonPos.pos, () => { Press(buttonPos.pos.x, buttonPos.pos.y); });
            buttonManager.ChangeText(buttonPos.pos, "");
        }

        foreach (GameButton gameButton in buttons) // initialize all buttons
        {
            gameButton.PreInitialze();
            gameButton.OnDisableButton += () => { AddCombo(gameButton); };
        }

        /*
         * Initialize timer
         */
        if (currentTime != null)
            currentTime.ClearTime();
        else
            currentTime = new ChartTime();

        currentTime.seconds = -3.0f;

        /*
         * Set the end false
         */
        isEnd = false;

        /*
         * Get chart and initialize chart information
         */
        chart = GameChartTransition.Instance.ChartInfo.Clone();
        SongName.text = $"Song: {chart.Song.name}";
        ChartDescription.text = $"ChartName:{chart.ChartName}\n\nChartMaker:{chart.ChartMaker}\n\nChartLevel:{chart.Level}";
    }

    private void Update()
    {
        if (isEnd)
        {
            return;
        }

        foreach (GameButton gameButton in buttons)
        {
            gameButton.ButtonUpdate();
        }

        /*
         * Get notes and show them at time
         */
        ChartNote[] notes = chart.GetNote(currentTime);
        if (notes != null || notes.Length > 0)
        {
            foreach(ChartNote note in notes)
            {
                float duration = note.endTime - note.startTime;
                foreach(Vector2Int pos in note.notesPos)
                {
                    buttons[pos.x * 3 + pos.y].Show(duration);
                }

                chart.RemoveChartNotes(note);
            }
        }

        /*
         * Timer
         */
        currentTime.seconds += Time.deltaTime;
        currentTime.CorrectTime();
        TimeText.text = currentTime.ToString();

        /*
         * Judge note
         */
        if (chart.ChartNotes.Count == 0)
        {
            foreach (GameButton button in buttons)
            {
                if (!button.IsDisable)
                {
                    return;
                }
            }
            isEnd = true;
            StartCoroutine(WaitForEnd());
        }
    }

    private void Press(int x, int y)
    {
        int pos = x * 3+ y;
        buttons[pos].PressEvent();
    }

    private void AddCombo(GameButton button)
    {
        GameScoreIncreaseType type = GameScoreIncreaseType.Miss;
        if (button.IsEnter)
        {
            type = score.IncreaseScore(button.AnimProcess);
        }
        else
        {
            score.AddMiss();
        }

        ComboText.text = $"Combo:\n{score.Combo}";
        ScoreTypeAnimator.SetTrigger("isShow");
        var stateInfo = ScoreTypeAnimator.GetCurrentAnimatorStateInfo(0);
        if (stateInfo.IsName("ScoreType"))
        {
            ScoreTypeAnimator.SetTrigger("isRestart");
        }
        ScoreTypeText.text = $"{type}";
    }
    
    private IEnumerator WaitForEnd()
    {
        yield return new WaitForSeconds(3.0f);
        InfoPanel.SetActive(false);
        EndPanel.SetActive(true);
        EndPanel.GetComponent<GameEndUiEvent>().Summary(score);
        this.gameObject.SetActive(false);
    }
}
